# /**
# * Copyright (c) 2022 Beijing Jiaotong University
# * PhotLab is licensed under [Open Source License].
# * You can use this software according to the terms and conditions of the [Open Source License].
# *
# * You may obtain a copy of [Open Source License] at: [https://open.source.license/]
# *
# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# *
# * See the [Open Source License] for more details.
# */
# /**
# * Author: Shihao Xie
# * Created: Jul. 12, 2022
# * Supported by: National Key Research and Development Program of China
# */

from phot_server.core.api_injector import api
from phot_server.manager.graph_manager import GraphManager
from phot_server.manager.library_manager import LibraryManager
from phot_server.rpc.graph_service.Graph import Processor


# gettext instructions
# D:/Python/Tools/i18n/
# pygettext.py -d graph -o locales/graph.pot service/graph_service.py
# msgfmt.py -o ./locales/cn/LC_MESSAGES/graph.mo ./locales/cn/LC_MESSAGES/graph
# msgfmt.py -o ./locales/en/LC_MESSAGES/graph.mo ./locales/en/LC_MESSAGES/graph


class GraphService:
    """
    该服务是计算图相关服务，可以通过这个服务管理用户拥有的计算图。
    调用该服务前，请确认已经做过连接服务相关操作并成功连接。例如：

    Examples:
        >>> from thrift import Thrift
        >>> from thrift.transport import TSocket
        >>> from thrift.transport import TTransport
        >>> from thrift.protocol import TBinaryProtocol
        >>> from photlab.graph_service.Graph import Client as graph_client
        >>> transport = TSocket.TSocket("localhost", 8080)
        >>> transport_protocol = TTransport.TBufferedTransport(transport)
        >>> protocol_factory = TBinaryProtocol.TBinaryProtocol(transport_protocol)
        >>> graph_client = graph_client(protocol_factory)
        >>> transport.open()

    具体使用可以查看测试用例 test/test_interface/test_graph.py

    注意：以下接口操作的计算图模型(PhotGraph)和计算图视图(RenderGraph)都是经过接口open_graph打开和加载后的数据对象。
    """

    def __init__(self):
        self.graph_manager = GraphManager()
        self.library_manager = LibraryManager()

    @api(Processor.process_open_graph)
    def open_graph(self, graph_path):
        """
        服务端打开一个计算图，加载计算图的数据并生成一个计算图模型(PhotGraph)和一个计算图视图(RenderGraph)，且这两个数据对象的名称相同，均为计算图ID。

        Args:
            graph_path (string): 计算图的路径

        Returns:
            PhotGraph: 计算图模型

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.open_graph("C://user//graph_1.phtg")
        """
        return self.graph_manager.open_graph(graph_path)

    @api(Processor.process_save_graph)
    def save_graph(self, graph_id):
        """
        服务端根据所给计算图ID，将计算图保存到加载该计算图的文件里。

        Args:
            graph_id (string): 需要保存的计算图ID

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.save_graph("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        self.graph_manager.save_graph(graph_id)

    @api(Processor.process_close_all_opened_graph)
    def close_all_opened_graph(self, save=True):
        """
        服务端根据所给计算图ID，将计算图保存到加载该计算图的文件里。

        Args:
            save (bool): 是否需要保存的计算图

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.save_graph("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        self.graph_manager.close_all_opened_graph(save)

    @api(Processor.process_save_graph_as)
    def save_graph_as(self, graph_path, graph_id):
        """
        服务端根据所给计算图ID和所给路径，将指定计算图另存为其他文件。

        Args:
            graph_path (string): 计算图保存的路径
            graph_id (string): 保存的计算图ID

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.save_graph_as("C://user//graph_2.phtg", "graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        self.graph_manager.graph_save_as(graph_id, graph_path)

    @api(Processor.process_close_graph)
    def close_graph(self, graph_id, ignore_change=False):
        """
        服务端根据所给计算图ID，关闭计算图。服务端会删除对应名称的计算图模型和计算图视图。
        在关闭之前最好先调用save_graph进行保存。

        Args:
            graph_id (string): 计算图ID
            ignore_change (bool): 是否忽略计算图的修改

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.close_graph("graph_name_YYYY-mm-dd_HH:MM:SS", False)

        """
        self.graph_manager.close_graph(graph_id, ignore_change)

    @api(Processor.process_new_graph)
    def new_graph(self, graph_name):
        """
        根据所给计算图ID新建一个新的计算图模型(PhotGraph)和一个新的计算图视图(RenderGraph)。

        Args:
            graph_name (string): 新的计算图名称

        Returns:
            PhotGraph: 计算图模型

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.new_graph("graph_name")

        """
        return self.graph_manager.new_empty_graph(graph_name)

    @api(Processor.process_get_graph)
    def get_graph(self, graph_id):
        """
        获取计算图模型。

        Args:
            graph_id (string): 计算图ID

        Returns:
            PhotGraph: 计算图模型

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_graph("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        return self.graph_manager.get_graph(graph_id)

    @api(Processor.process_get_render_graph)
    def get_render_graph(self, graph_id):
        """
        获取计算图视图。

        Args:
            graph_id (string): 计算图ID

        Returns:
            RenderGraph: 计算图视图

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_render_graph("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        return self.graph_manager.get_render_graph(graph_id)

    @api(Processor.process_rename_graph)
    def rename_graph(self, graph_id, new_name):
        """
        重命名对应的计算图模型和计算图视图。

        Args:
            graph_id (string): 计算图ID
            new_name (string): 新的计算图ID

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.rename_graph("graph_name_YYYY-mm-dd_HH:MM:SS", "graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        self.graph_manager.rename_graph(graph_id, new_name)

    @api(Processor.process_get_opened_graph_list)
    def get_opened_graph_list(self):
        """
        获取所有已经打开的计算图

        Args:

        Returns:
            map<string, string>: 返回一个包含<graphId, graphName>的字典

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_opened_graph_list()

        """
        return self.graph_manager.get_opened_graph_list()

    @api(Processor.process_alter_graph_attribute)
    def alter_graph_attribute(self, graph_id, attribute_name, attribute_value):
        """
        修改计算图属性。

        Args:
            graph_id (string): 计算图ID
            attribute_name (string): 属性名称
            attribute_value (string): 新属性值

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.alter_graph_attribute("graph_name_YYYY-mm-dd_HH:MM:SS", "author", "Me")

        """
        self.graph_manager.alter_graph_attribute(graph_id, attribute_name, attribute_value)

    @api(Processor.process_get_graph_parameters)
    def get_graph_parameters(self, graph_id):
        """
        获取所有计算图参数。

        Args:
            graph_id (string): 计算图ID

        Returns:
            list<PhotParameter>: 计算图参数列表

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_graph_parameters("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        return self.graph_manager.get_graph_parameters(graph_id)

    @api(Processor.process_get_graph_parameter)
    def get_graph_parameter(self, graph_id, graph_parameter_name):
        """
        获取一个计算图参数。

        Args:
            graph_id (string): 计算图ID
            graph_parameter_name (string): 参数名称

        Returns:
            PhotParameter: 计算图变量

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_graph_parameter("graph_name_YYYY-mm-dd_HH:MM:SS", "graph_paramter_1")

        """
        return self.graph_manager.get_graph_parameter(graph_id, graph_parameter_name)

    @api(Processor.process_alter_graph_parameter)
    def alter_graph_parameter(self, graph_id, graph_parameter_name, graph_parameter):
        """
        修改一个计算图参数。

        Args:
            graph_id (string): 计算图ID
            graph_parameter_name (string): 参数名称
            graph_parameter (PhotParameter) : 参数对象

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> parameter = PhotParameter(name="graph_parameter_1",
                                          nameTag="global parameter",
                                          dataType="int",
                                          value="1550",
                                          unit="nm",
                                          photUnit="nm",
                                          enumItem=None,
                                          interval="(0,inf)",
                                          category="global",
                                          description="A global parameter that is related to some components of graph.")
            >>> graph_client.alter_graph_parameter("graph_name_YYYY-mm-dd_HH:MM:SS", "graph_parameter_1", paramter)

        """
        self.graph_manager.alter_graph_parameter(graph_id, graph_parameter_name, graph_parameter)

    @api(Processor.process_alter_graph_parameters)
    def alter_graph_parameters(self, graph_id, graph_parameters):
        """
        修改所有计算图参数。

        Args:
            graph_id (string): 计算图ID
            graph_parameters (list<PhotParameter>) : 参数对象列表

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> parameters = [PhotParameter(name="graph_parameter_1",
                                            nameTag="global parameter",
                                            dataType="int",
                                            value="1550",
                                            unit="nm",
                                            photUnit="nm",
                                            enumItem=None,
                                            interval="(0,inf)",
                                            category="global",
                                            description="A global parameter that is related to some components of graph."),
                              PhotParameter(name="graph_parameter_2",
                                            nameTag="simulation option",
                                            dataType="enum",
                                            value="option_1",
                                            unit=None,
                                            photUnit=None,
                                            enumItem="option_1|option_2|option_3",
                                            interval=None,
                                            category="simulation",
                                            description="A option of simulation.")]
            >>> graph_client.alter_graph_parameters("graph_name_YYYY-mm-dd_HH:MM:SS", paramters)

        """
        self.graph_manager.alter_graph_parameters(graph_id, graph_parameters)

    @api(Processor.process_add_graph_parameter)
    def add_graph_parameter(self, graph_id, graph_parameter):
        """
        添加一个计算图参数。

        Args:
            graph_id (string): 计算图ID
            graph_parameter (PhotParameter) : 参数对象

        Returns:
            PhotParameter: 计算图变量

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> parameters = PhotParameter(name="graph_parameter_1",
                                           nameTag="global parameter",
                                           dataType="int",
                                           value="1550",
                                           unit="nm",
                                           photUnit="nm",
                                           enumItem=None,
                                           interval="(0,inf)",
                                           category="global",
                                           description="A global parameter that is related to some components of graph.")
            >>> graph_client.add_graph_parameter("graph_name_YYYY-mm-dd_HH:MM:SS", paramters)

        """
        return self.graph_manager.add_graph_parameter(graph_id, graph_parameter)

    @api(Processor.process_delete_graph_parameter)
    def delete_graph_parameter(self, graph_id, graph_parameter_name):
        """
        删除一个计算图参数。

        Args:
            graph_id (string): 计算图ID
            graph_parameter_name (string) : 参数名称

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.delete_graph_parameter("graph_name_YYYY-mm-dd_HH:MM:SS", "graph_parameter_1")

        """
        self.graph_manager.delete_graph_parameter(graph_id, graph_parameter_name)

    @api(Processor.process_get_component)
    def get_component(self, graph_id, component_id):
        """
        从计算图获取一个组件。

        Args:
            graph_id (string): 计算图ID
            component_id (int) : 组件id

        Returns:
            PhotComponent: 组件模型对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_component("graph_name_YYYY-mm-dd_HH:MM:SS", 0)

        """
        return self.graph_manager.get_component(graph_id, component_id)

    @api(Processor.process_get_components)
    def get_components(self, graph_id):
        """
        从计算图获取所有组件。

        Args:
            graph_id (string): 计算图ID

        Returns:
            list<PhotComponent>: 组件模型对象列表

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_components("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        return self.graph_manager.get_components(graph_id)

    @api(Processor.process_add_component)
    def add_component(self, graph_id, component):
        """
        向计算图添加一个组件模型对象。

        Args:
            graph_id (string): 计算图ID
            component (PhotComponent): 组件模型对象

        Returns:
            PhotComponent: 组件模型对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> component = PhotComponent(name="test component",
                                          calculationMethod="test",
                                          parallelComputingMethod="CPU",
                                          isAnalyzer="False",
                                          isClass="False",
                                          description="Component for test. It is not real.",
                                          category="/",
                                          path="/test_component.phtc",
                                          parameters=[PhotParameter(name="num_bits",
                                                                    dataType="int",
                                                                    value="393216",
                                                                    unit="bit",
                                                                    photUnit="bit",
                                                                    nameTag="Number of bits",
                                                                    interval="(0,inf)",
                                                                    category="/",
                                                                    description="Number of bits"
                                                                    )])
            >>> graph_client.add_component("graph_name_YYYY-mm-dd_HH:MM:SS", component)

        """
        return self.graph_manager.add_component(graph_id, component)

    @api(Processor.process_add_component_from_library)
    def add_component_from_library(self, graph_id, component_path, rect):
        """
        从组件库中选择一个组件并添加到计算图的指定位置，即将组件同时加入计算图模型(PhotGraph)和计算图视图(RenderGraph)。

        Args:
            graph_id (string): 计算图ID
            component_path (string): 组件在组件库的路径
            component_id (int): 组件id
            rect (RenderRect): 描述组件位置和大小的矩形

        Returns:
            PhotComponent: 组件模型对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.add_component_from_library("graph_name_YYYY-mm-dd_HH:MM:SS", "./fiber.phtc", RenderRect(x=0, y=0, width=10, height=10))

        """
        return self.graph_manager.add_component_from_library(graph_id, component_path, rect)

    @api(Processor.process_delete_component)
    def delete_component(self, graph_id, component_id, cascade_delete=False):
        """
        删除计算图模型中的一个组件模型对象。
        如果cascade_delete=True:则同时删除计算图模型(PhotGraph)的组件模型对象和计算图视图(RenderGraph)的组件渲染对象。此外还会删除与组件相关的连接模型对象(PhotGraphLink)和连接渲染对象(RenderRoute)。
        如果cascade_delete=False:则只删除计算图模型(PhotGraph)的组件模型对象。
        默认cascade_delete=False。

        Args:
            graph_id (string): 计算图ID
            component_id (int): 组件id
            cascade_delete (bool): 是否删除组件视图对象标志

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.delete_component("graph_name_YYYY-mm-dd_HH:MM:SS", "./fiber.phtc", 1, True)

        """
        self.graph_manager.delete_component(graph_id, component_id, cascade_delete)

    @api(Processor.process_alter_component)
    def alter_component(self, graph_id, component):
        """
        修改一个组件模型对象

        Args:
            graph_id (string): 计算图ID
            component (PhotComponent): 组件模型对象

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> component = PhotComponent(componentId=100,
                                          name="test component",
                                          calculationMethod="test",
                                          parallelComputingMethod="CPU",
                                          isAnalyzer="False",
                                          isClass="False",
                                          description="Component for test. It is not real.",
                                          category="/",
                                          path="/test_component.phtc",
                                          parameters=[PhotParameter(name="num_bits",
                                                                    dataType="int",
                                                                    value="393216",
                                                                    unit="bit",
                                                                    photUnit="bit",
                                                                    nameTag="Number of bits",
                                                                    interval="(0,inf)",
                                                                    category="/",
                                                                    description="Number of bits"
                                                                    )])
            >>> graph_client.alter_component("graph_name_YYYY-mm-dd_HH:MM:SS", component)

        """
        self.graph_manager.alter_component(graph_id, component)

    @api(Processor.process_get_render_node)
    def get_render_node(self, graph_id, component_id):
        """
        获取一个组件渲染对象。

        Args:
            graph_id (string): 计算图ID
            component_id (int): 组件id

        Returns:
            RenderGraphNode: 组件渲染对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_render_node("graph_name_YYYY-mm-dd_HH:MM:SS", 100)

        """
        return self.graph_manager.get_render_node(graph_id, component_id)

    @api(Processor.process_get_render_nodes)
    def get_render_nodes(self, graph_id):
        """
        获取计算图视图里所有组件渲染对象。

        Args:
            graph_id (string): 计算图ID

        Returns:
            list<RenderGraphNode>: 组件渲染对象列表

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_render_nodes("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        return self.graph_manager.get_render_nodes(graph_id)

    @api(Processor.process_add_render_node)
    def add_render_node(self, graph_id, node):
        """
        添加一个组件渲染对象到计算图视图。

        Args:
            graph_id (string): 计算图ID
            node (RenderGraphNode): 组件渲染对象

        Returns:
            RenderGraphNode: 组件渲染对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> render_node = RenderGraphNode(iconName="Mock Name",
                                              description="Component for test. It is not real.",
                                              rect=RenderRect(x=10, y=120, width=10, height=10),
                                              ports=[RenderPort(portId=0,
                                                                direction=PortDirection.OUT,
                                                                aspect=PortAspect.RIGHT,
                                                                location=0,
                                                                name="Output signal",
                                                                description="Output a binary signal.")])
            >>> graph_client.add_render_node("graph_name_YYYY-mm-dd_HH:MM:SS", render_node)

        """
        return self.graph_manager.add_render_node(graph_id, node)

    @api(Processor.process_delete_render_node)
    def delete_render_node(self, graph_id, component_id, cascade_delete=False):
        """
        删除计算图视图一个组件渲染对象。
        如果cascade_delete=True:则同时删除计算图模型(PhotGraph)的组件模型对象和计算图视图(RenderGraph)的组件渲染对象。此外还会删除与组件相关的连接模型对象(PhotGraphLink)和连接渲染对象(RenderRoute)。
        如果cascade_delete=False:则只删除算图视图(RenderGraph)的组件渲染对象。
        默认cascade_delete=False。

        Args:
            graph_id (string): 计算图ID
            component_id (int): 组件id
            cascade_delete (bool): 是否删除组件模型对象标志
        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.delete_render_node("graph_name_YYYY-mm-dd_HH:MM:SS", 100, True)

        """
        self.graph_manager.delete_render_node(graph_id, component_id, cascade_delete)

    @api(Processor.process_set_render_node_rect)
    def set_render_node_rect(self, graph_id, component_id, rect):
        """
        修改一个组件渲染对象位置和大小数据。

        Args:
            graph_id (string): 计算图ID
            component_id (int): 组件id
            rect (RenderRect): 描述组件位置和大小的矩形

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.set_render_node_rect("graph_name_YYYY-mm-dd_HH:MM:SS", 100, RenderRect(x=10, y=120, width=10, height=10))

        """
        self.graph_manager.set_render_node_rect(graph_id, component_id, rect)

    @api(Processor.process_render_node_move_to)
    def render_node_move_to(self, graph_id, component_id, x, y):
        """
        修改一个组件渲染对象位置和大小数据。

        Args:
            graph_id (string): 计算图ID
            component_id (int): 组件id
            x (int): 组件位置x
            y (int): 组件位置y

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.set_render_node_rect("graph_name_YYYY-mm-dd_HH:MM:SS", 100, x=10, y=120)

        """
        self.graph_manager.render_node_move_to(graph_id, component_id, x, y)

    @api(Processor.process_alter_render_node)
    def alter_render_node(self, graph_id, node):
        """
        修改一个组件渲染对象。

        Args:
            graph_id (string): 计算图ID
            node (RenderGraphNode): 组件渲染对象

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> render_node = RenderGraphNode(nodeId=100,
                                              iconName="Mock Name 2",
                                              description="Mock description",
                                              rect=RenderRect(x=10, y=10, width=10, height=10),
                                              ports=[RenderPort(portId=0,
                                                                direction=PortDirection.OUT,
                                                                aspect=PortAspect.RIGHT,
                                                                location=0,
                                                                name="Output signal",
                                                                description="Output a binary signal.")])
            >>> graph_client.alter_render_node("graph_name_YYYY-mm-dd_HH:MM:SS", render_node)

        """
        self.graph_manager.alter_render_node(graph_id, node)

    @api(Processor.process_add_link)
    def add_link(self, graph_id, link):
        """
        添加一个连接模型对象。

        Args:
            graph_id (string): 计算图ID
            link (PhotGraphLink): 连接模型对象

        Returns:
            PhotGraphLink: 连接模型对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> link = PhotGraphLink(srcNodeId=0,srcPortId=1,dstNodeId=1,dstPortId=0)
            >>> graph_client.add_link("graph_name_YYYY-mm-dd_HH:MM:SS", link)

        """
        return self.graph_manager.add_link(graph_id, link)

    @api(Processor.process_get_links)
    def get_links(self, graph_id):
        """
        获取所有连接模型对象。

        Args:
            graph_id (string): 计算图ID

        Returns:
            list<PhotGraphLink>: 连接模型列表

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_links("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        return self.graph_manager.get_links(graph_id)

    @api(Processor.process_get_link)
    def get_link(self, graph_id, link_id):
        """
        获取一个连接模型对象。

        Args:
            graph_id (string): 计算图ID
            link_id (int): 连接id

        Returns:
            PhotGraphLink: 连接模型对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_link("graph_name_YYYY-mm-dd_HH:MM:SS", 0)

        """
        return self.graph_manager.get_link(graph_id, link_id)

    @api(Processor.process_delete_link)
    def delete_link(self, graph_id, link_id, delete_render=False):
        """
        删除一个连接模型对象。
        如果cascade_delete=True:则同时删除连接模型对象(PhotGraphLink)和连接渲染对象(RenderRoute)。
        如果cascade_delete=False:则只删除连接模型对象(PhotGraphLink)。
        默认cascade_delete=False。

        Args:
            graph_id (string): 计算图ID
            link_id (int): 连接id
            delete_render (bool): 是否删除连接渲染对象标志

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.delete_link("graph_name_YYYY-mm-dd_HH:MM:SS", 0, True)

        """
        self.graph_manager.delete_link(graph_id, link_id, delete_render)

    @api(Processor.process_alter_link)
    def alter_link(self, graph_id, link):
        """
        修改一个连接模型对象。

        Args:
            graph_id (string): 计算图ID
            link (PhotGraphLink): 连接模型对象

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> link = PhotGraphLink(linkId=0,srcNodeId=1,srcPortId=1,dstNodeId=2,dstPortId=0)
            >>> graph_client.alter_link("graph_name_YYYY-mm-dd_HH:MM:SS", link)

        """
        self.graph_manager.alter_link(graph_id, link)

    @api(Processor.process_add_render_route)
    def add_render_route(self, graph_id, route):
        """
        添加一个连接渲染对象。

        Args:
            graph_id (string): 计算图ID
            route (RenderRoute): 连接渲染对象

        Returns:
            RenderRoute: 连接模型对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> route = RenderRoute(routeId=0,path=[RenderWayPoint(x=20, y=20, fixed=False),
                                                    RenderWayPoint(x=20, y=30, fixed=False),
                                                    RenderWayPoint(x=10, y=30, fixed=False),
                                                    RenderWayPoint(x=10, y=35, fixed=False)])
            >>> graph_client.add_render_route("graph_name_YYYY-mm-dd_HH:MM:SS", route)

        """
        return self.graph_manager.add_render_route(graph_id, route)

    @api(Processor.process_get_render_route)
    def get_render_route(self, graph_id, link_id):
        """
        获取一个连接渲染对象。

        Args:
            graph_id (string): 计算图ID
            link_id (int): 连接id

        Returns:
            RenderRoute: 连接模型对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_render_route("graph_name_YYYY-mm-dd_HH:MM:SS", 0)

        """
        return self.graph_manager.get_render_route(graph_id, link_id)

    @api(Processor.process_delete_render_route)
    def delete_render_route(self, graph_id, link_id, delete_model=False):
        """
        删除一个连接渲染对象。
        如果cascade_delete=True:则同时删除连接模型对象(PhotGraphLink)和连接渲染对象(RenderRoute)。
        如果cascade_delete=False:则只删除连接渲染对象(RenderRoute)。
        默认cascade_delete=False。

        Args:
            graph_id (string): 计算图ID
            link_id (int): 连接id
            delete_model (bool): 是否删除连接模型对象

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.delete_render_route("graph_name_YYYY-mm-dd_HH:MM:SS", 0, True)

        """
        self.graph_manager.delete_render_route(graph_id, link_id, delete_model)

    @api(Processor.process_set_render_route_path)
    def set_render_route_path(self, graph_id, link_id, points):
        """
        设置一个连接渲染对象的路径中间点。

        Args:
            graph_id (string): 计算图ID
            link_id (int): 连接id
            points (list<RenderWayPoint>): 连接渲染对象的中间节点列表

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> points = [RenderWayPoint(x=20, y=30, fixed=False),
                          RenderWayPoint(x=10, y=30, fixed=False),
                          RenderWayPoint(x=10, y=35, fixed=False)]
            >>> graph_client.set_render_route_path("graph_name_YYYY-mm-dd_HH:MM:SS", 0, point_list)

        """
        self.graph_manager.set_render_route_path(graph_id, link_id, points)

    @api(Processor.process_add_text_area)
    def add_text_area(self, graph_id, text_area):
        """
        添加一个文本区域。

        Args:
            graph_id (string): 计算图ID
            text_area (RenderTextArea): 文本区域对象

        Returns:
            RenderTextArea: 文本区域对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> text_area = RenderTextArea(text="Hello!",
                                           textColor="#000000",
                                           font="Times New Roman",
                                           fontSize=12,
                                           rect=RenderRect(x=0, y=10, width=10, height=10),
                                           horizontalAlign=TextAlign.CENTER,
                                           verticalAlign=TextAlign.CENTER,
                                           fillColor="#FFFFFF",
                                           lineColor="#FFFFFF",
                                           lineWeight="1")
            >>> graph_client.add_text_area("graph_name_YYYY-mm-dd_HH:MM:SS", text_area)

        """
        return self.graph_manager.add_text_area(graph_id, text_area)

    @api(Processor.process_get_text_area)
    def get_text_area(self, graph_id, text_id):
        """
        获取一个文本区域。

        Args:
            graph_id (string): 计算图ID
            text_id (int): 文本区域id

        Returns:
            RenderTextArea: 文本区域对象

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.get_text_area("graph_name_YYYY-mm-dd_HH:MM:SS")

        """
        return self.graph_manager.get_text_area(graph_id, text_id)

    @api(Processor.process_delete_text_area)
    def delete_text_area(self, graph_id, text_id):
        """
        删除一个文本区域。

        Args:
            graph_id (string): 计算图ID
            text_id (int): 文本区域id

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.delete_text_area("graph_name_YYYY-mm-dd_HH:MM:SS", 0)

        """
        self.graph_manager.delete_text_area(graph_id, text_id)

    @api(Processor.process_alter_text_area)
    def alter_text_area(self, graph_id, text_area):
        """
        修改一个文本区域。

        Args:
            graph_id (string): 计算图ID
            text_area (RenderTextArea): 文本区域对象

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> text_area = RenderTextArea(textId=0,
                                           text="Hello!",
                                           textColor="#FFFFFF",
                                           font="Times New Roman",
                                           fontSize=14,
                                           rect=RenderRect(x=0, y=10, width=10, height=10),
                                           horizontalAlign=TextAlign.CENTER,
                                           verticalAlign=TextAlign.CENTER,
                                           fillColor="#FFFFFF",
                                           lineColor="#FFFFFF",
                                           lineWeight="1")
            >>> graph_client.alter_text_area("graph_name_YYYY-mm-dd_HH:MM:SS", text_area)

        """
        self.graph_manager.alter_text_area(graph_id, text_area)

    @api(Processor.process_set_text)
    def set_text(self, graph_id, text_id, text):
        """
        设置一个文本区域的文本内容。

        Args:
            graph_id (string): 计算图ID
            text_id (int): 文本区域id
            text (string): 文本内容

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.set_text("graph_name_YYYY-mm-dd_HH:MM:SS", 0, "Photlab!")

        """
        self.graph_manager.set_text(graph_id, text_id, text)

    @api(Processor.process_set_text_area_rect)
    def set_text_area_rect(self, graph_id, text_id, rect):
        """
        设置一个文本区域的位置和大小。

        Args:
            graph_id (string): 计算图ID
            text_id (int): 文本区域id
            rect (RenderRect): 描述文本区域位置和大小的矩形

        Returns:
            无

        Raises:
            PhotError: 异常代码查看PhotError的exception_code

        Examples:
            >>> graph_client.set_text_area_rect("graph_name_YYYY-mm-dd_HH:MM:SS", 0, RenderRect(x=20, y=0, width=10, height=10))

        """
        self.graph_manager.set_text_area_rect(graph_id, text_id, rect)

    @api(Processor.process_revocation)
    def revocation(self, graph_id):
        pass

    @api(Processor.process_recover)
    def recover(self, graph_id):
        pass


if __name__ == "__main__":
    GraphService()
